<template>
    <div class="video" :style="{width:`${width}px`}">
        <div class="video-context" :style="{height:`${height}px`,display: 'flex',justifyContent: 'center',alignItems: 'center'}">
            <template v-for="(page,idx) in pages">
                <canvas
                        :key="idx"
                        :width="width"
                        :height="height"
                        :style="{background:`url('${imgs.length>0?imgs[idx]:''}')`,'background-size':'cover'}"
                        :id="'canvas'+memberId+'-'+page"
                        v-show="pages[pageIdx]==page"
                ></canvas>
            </template>
            <canvas
                    :width="width"
                    :height="height"
                    style="position: absolute;top: 0;left: 0;"
                    id="canvas-bak"
            ></canvas>
        </div>
        <div class="video-foot">
            <div class="video-progress" @click="clickProgress" @mousedown="mousedownProgress" @mouseup="mouseupProgress"
                 @mousemove="mousemoveProgress" @mouseleave="mouseupProgress">
                <div class="line" :style="{width: (playTime/videoTime)*100 + '%'}">
                    <div class="video-dot"></div>
                </div>
            </div>
            <div class="video-info">
                <div class="video-page">
                    <span class="iconfont icon-zuo" @click="pageChange(1)"></span>
                    {{pageIdx+1}}/{{pages.length}}
                    <span
                            class="iconfont icon-you"
                            @click="pageChange(2)"
                    ></span>
                </div>
                <div class="video-play">
                    <span v-show="btnState === 0 && !stateChanged" @click="stateChange"
                          class="icon-bofang iconfont"></span>
                    <span v-show="btnState === 1 || stateChanged" @click="stateChange"
                          class="icon-zanting iconfont"></span>
                </div>
                <div class="video-time">
                    {{countMinutes(playTime,'mm:ss').desc }}/{{countMinutes(videoTime,'hh:mm:ss').desc }}
                </div>

                <div class="video-speed">
                    <el-select v-model="playSpeed" size="mini">
                        <el-option
                                v-for="item in playSpeedArr"
                                :key="item.value"
                                :label="item.name"
                                :value="item.value"
                        ></el-option>
                    </el-select>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
  require('../utils/FormatDate.js');
  import {Utils} from '../utils/Utils';
  import {CanvasConfig} from '../config/CanvasConfig';

  export default {
    name: 'hcVideoComponent',
    data() {
      return {
        flashList: {},
        videoTime: 0,
        playTime: 0,
        btnState: 0, //0暂停 1播放
        timer: 0,
        pageIdx: 0,
        totalPage: 1,
        playSpeed: 1, //默认5 就是正常速度
        playSpeedArr: [
          {name: '1.0 x', value: 1},
          {name: '2.0 x', value: 2},
          {name: '4.0 x', value: 4},
          {name: '8.0 x', value: 8},
          {name: '16.0 x', value: 16},
          {name: '50.0 x', value: 50}
        ],
        curReadIdx: 0,

        timeDrawLast: {}, // 根据时间绘点的上一笔的描点信息
        runTime: 0,
        writeData: [],
        debuggerOpt: {
          isOpen: true,
          start: {
            x: 0,
            y: 0
          },
          distance: {
            x: 0,
            y: 0
          }
        },
        dragStatus: false,
        stateChanged: false
      };
    },
    watch: {
      width: function() {
        //宽度变化以后表格需要重绘

        this.resetData();
      },
      rawData: function() {

        this.resetData();
      }
    },
    mounted() {
      this.resetData();
    },
    activated() {
      this.resetData();
    },
    methods: {
      mousemoveProgress(e) {
        e.preventDefault();
        e.stopPropagation();
        if (this.dragStatus) {
          this.clearBoard();
          for (let ele of e.path) {
            if (ele.className === 'video-progress') {
              // this.playTime = Math.floor(this.videoTime * e.layerX / ele.clientWidth);
              this.runTime = Math.floor(((this.videoTime) * 10) * (((e.layerX / ele.clientWidth) <= 1) ? (e.layerX / ele.clientWidth) : 1));
              break;
            }
          }
          this.drawOnTime();
          return false;
        } else {
          return false;
        }
      },
      mousedownProgress(e) {
        // console.log('mousedown');
        e.preventDefault();
        e.stopPropagation();
        if (this.btnState === 1) {
          this.stateChange();
          this.stateChanged = true;
        }
        this.dragStatus = true;
        return false;
      },
      mouseupProgress(e) {
        // console.log('mouseup');
        e.preventDefault();
        e.stopPropagation();
        if (this.dragStatus === true && this.stateChanged === true) {
          this.stateChange();
          this.stateChanged = false;
        }
        this.dragStatus = false;
        return false;
      },
      clickProgress(e) {
        // console.log('click');
        e.preventDefault();
        e.stopPropagation();
        this.clearBoard();
        for (let ele of e.path) {
          if (ele.className === 'video-progress') {
            // this.playTime = Math.floor(this.videoTime * e.layerX / ele.clientWidth);
            this.runTime = Math.floor(((this.videoTime) * 10) * (((e.layerX / ele.clientWidth) <= 1) ? (e.layerX / ele.clientWidth) : 1));
            break;
          }
        }
        this.drawOnTime();
        return false;
      },
      resetData() {

        try {
          $Event.onOne('btn-play-state-reset', ({state, speed, page}) => {

            if (this.btnState != state) {
              this.stateChange();
            }
            this.playSpeed = speed;
            this.pageChangeNum(page);
          });
        } catch (e) {

        }
        this.clearBoard();
        if (this.rawData) {
          this.writeData = Utils.handleAnswerData(this.rawData);
          this.initConfig();
          this.$nextTick(() => {
            this.flashList = this.countFlash(this.width, this.height);
            this.resetVideo();
            this.drawAll();
          });
        }
      },
      initConfig() {
        this.pages = this.countPages(this.writeData);
        this.totalPage = this.pages.length;
        this.videoTime = this.writeData.maxTime;

      },
      countFlash(canvasWidth, canvasHeight) {
        let flashList = {};
        for (let i = 0; i < this.totalPage; i++) {

          let pageInfo = this.pages[i];
          let cav = document.getElementById(`canvas${this.memberId}-${pageInfo}`).getContext('2d');
          let dots = this.writeData[pageInfo];
          if (!dots) {

            continue;
          }
          let top = 0,
            right = 0,
            left = canvasWidth,
            bottom = canvasHeight,
            flash = 1;
          for (let j in dots) {
            let timeDots = dots[j];
            for (let k = 0; k < timeDots.length; k++) {
              let dot = timeDots[k];
              let {x, y} = {x: dot.x, y: dot.y};
              if (y > top) top = y;
              if (y < bottom) bottom = y;
              if (x > right) right = x;
              if (x < left) left = x;
            }
          }
          let width = -left + right,
            height = top - bottom;
          flash = width / (canvasWidth * 0.9) > height / (canvasHeight * 0.9) ? width / (canvasWidth * 0.9) : height / (canvasHeight * 0.9);
          flash = flash > 0.11 && flash || 0.11;
          // flash *= this.getNums();
          // console.log(flash);
          cav.canvas.width = width / flash + 20;
          cav.canvas.height = height / flash + 20;
          flashList[pageInfo] = ({flash, left, bottom});
        }
        return flashList;
      },
      getCurCtx() {
        var canvas = document.getElementById(
          `canvas${this.memberId}-${this.pages[this.pageIdx]}`
        );
        return canvas.getContext('2d');
      },
      stateChange() {
        if (this.btnState == 0) {
          if (this.playTime >= this.videoTime) {
            this.resetVideo();
          }
          this.btnState = 1;
          this.timeGo();
        } else {
          clearTimeout(this.timer);
          this.btnState = 0;
        }
      },
      pageChange(type) {
        //1减2加

        if (this.btnState === 1) this.stateChange();
        if (type == 1) {
          this.pageChangeNum(this.pageIdx -= 1);
        } else {
          this.pageChangeNum(this.pageIdx += 1);
        }
      },
      pageChangeNum(num) {

        if (num < 0 || num >= this.totalPage - 1) {
          return;
        }
        this.pageIdx = num;
      },

      draw: function(data) {

        let rawData = data.answerRawData;
        let page = rawData['code-page'];

        let newData = Utils.handleAnswerData(JSON.stringify(rawData));
        //一个笔画包只有一个页码

        this.writeData = Utils.handleAnswerData(
          JSON.stringify(rawData),
          this.writeData
        );
        if (this.pages.indexOf(page) < 0) {
          this.initConfig();
          this.$nextTick(() => {
            this.drawPackge(newData);
          });
        } else {
          this.drawPackge(newData);
        }

        this.pageIdx = this.pages.indexOf(page);
      },
      drawArr(temp, pageIdx, changed) {
        var canvas = document.getElementById(
          `canvas${this.memberId}-${this.pages[pageIdx]}`
        );
        let ctx;
        try {
          ctx = canvas.getContext('2d');
        } catch (e) {
          return;
        }
        ctx.beginPath();



        ctx.lineWidth = CanvasConfig.lineWidth;
        let last = this.timeDrawLast;
        for (let i = 0; i < temp.length; i++) {
          let dot = temp[i];
          let idx = dot.idx;

          let flash = this.flashList[this.pages[pageIdx]].flash;
          let left = this.flashList[this.pages[pageIdx]].left;
          let bottom = this.flashList[this.pages[pageIdx]].bottom;
          if (last && last.idx != idx) {

            ctx.moveTo((last.x - left) / flash + 10, (last.y - bottom) / flash + 10);
          } else {

            ctx.moveTo((last.x - left) / flash + 10, (last.y - bottom) / flash + 10);
            ctx.lineTo((dot.x - left) / flash + 10, (dot.y - bottom) / flash + 10);
          }

          last = dot;
        }
        ctx.stroke();
        this.timeDrawLast = last;
      },
      countPages(data) {
        /**
         let pages = [];
         for (var page in data) {

                    if (parseInt(page) || parseInt(page) == 0) {

                        pages.push(parseInt(page));
                    }
                }**/

        return this.pages;
      },
      drawByTime: function() {
        //一 period 调用一次

        for (let i = 0; i < this.pages.length; i++) {
          var toDrawData = this.writeData[this.pages[i]];

          if (!toDrawData) {
            continue;
          }
          this.playTime = Math.floor(
            (this.runTime * this.writeData.period) / 1000
          );

          let temp = toDrawData[this.runTime];
          if (!temp || temp.length == 0) {
            continue;
          }
          this.pageIdx = i;
          this.drawArr(temp, i);
        }
        this.runTime++;
      },
      drawOnTime: function() {

        for (let i = 0; i < this.pages.length; i++) {
          var toDrawData = this.writeData[this.pages[i]];
          if (!toDrawData) {
            continue;
          }
          this.playTime = Math.floor(
            (this.runTime * this.writeData.period) / 1000
          );
          if (this.playTime > this.videoTime) {
            this.playTime = this.videoTime;
          }
          for (let j = 0; j < Math.floor(this.runTime); j++) {
            let temp = toDrawData[j];
            // console.log(temp);
            if (!temp || temp.length === 0) {
              continue;
            }
            this.pageIdx = i;
            this.drawArr(temp, i);
          }
        }
        // this.runTime++;
      },
      drawAll() {
        //一次将所有之前的轨迹画完

        this.drawPackge(this.writeData, true, false);
        this.drawPackge(this.writeData, false, false);
      },

      drawPackge: (() => {
        var lastDot = {};
        return function(data, isReset) {
          if (isReset) {
            lastDot = {};
            return;
          }

          let pages = this.countPages(data);

          for (let i = 0; i < pages.length; i++) {
            //绘制所有点的数据
            let page = pages[i];
            let flash = this.flashList[page].flash;
            let left = this.flashList[page].left;
            let bottom = this.flashList[page].bottom;
            var toDrawData = data[page];
            let canvas = document.getElementById(
              `canvas${this.memberId}-${page}`
            );
            let ctx = canvas.getContext('2d');
            ctx.lineWidth = CanvasConfig.lineWidth;
            ctx.beginPath();
            for (var key in toDrawData) {
              let temp = toDrawData[key];
              for (let j = 0; j < temp.length; j++) {
                var dot = temp[j];

                if (dot.idx == lastDot.idx) {
                  ctx.moveTo((lastDot.x - left) / flash + 10, (lastDot.y - bottom) / flash + 10);
                  // ctx.moveTo(
                  //   lastDot.x * this.getNums(),
                  //   lastDot.y * this.getNums()
                  // );
                  ctx.lineTo((dot.x - left) / flash + 10, (dot.y - bottom) / flash + 10);
                  // ctx.lineTo(dot.x * this.getNums(), dot.y * this.getNums());
                } else {
                  ctx.moveTo((dot.x - left) / flash + 10, (dot.y - bottom) / flash + 10);
                  // ctx.moveTo(dot.x * this.getNums(), dot.y * this.getNums());
                }
                lastDot = dot;
              }

            }
            ctx.stroke();
            ctx.closePath();
          }
        };
      })(),

      getNums() {
        return this.width / 210;
      },
      timeGo() {
        if (this.btnState == 1) {
          if (this.videoTime === 0) {
            this.$message({
              showClose: true,
              message: '当前无可播放内容哦',
              type: 'error'
            });
            return;
          }
          if (this.playTime >= this.videoTime) {
            this.pauseVideo();
            return;
          }

          if (this.runTime == 0) {
            this.clearBoard();
          }

          this.timer = setTimeout(() => {
            this.drawByTime(this.playTime);
            return this.timeGo();
          }, this.writeData.period / this.playSpeed);
        }
      },
      delVideo() {
        this.pauseVideo();
        this.$emit('del');
      },
      countMinutes(time, fmt) {
        return Utils.countMinutes(time, fmt);
      },
      pauseVideo() {
        this.btnState = 0;
        clearTimeout(this.timer);
      },
      resetVideo() {
        this.btnState = 0;
        this.playTime = 0;
        this.drawPackge('', -1);
        this.runTime = 0;
        this.timeDrawLast = {};
      },
      clearBoard() {
        for (let i = 0; i < this.pages.length; i++) {
          let page = this.pages[i];
          //从0开始 清除笔画
          let canvas = document.getElementById(`canvas${this.memberId}-${page}`);
          let ctx = canvas.getContext('2d');

          ctx.clearRect(0, 0, this.width, this.height);
          this.curReadIdx = 0;
        }
      }
    },
    props: {

      memberId: {
        default: function() {
          return [];
        }
      },
      pages: {
        type: Array,
        default: function() {
          return [];
        }
      },
      width: {
        default: function() {
          return 800;
        }
      },
      height: {
        default: function() {
          return 500;
        }
      },
      imgs: {
        type: Array,
        default: function() {
          return [];
        }
      },
      rawData: {
        default: function() {
          return '';
        }
      }
    }
  };
</script>

<style scoped>
    .video {
        background-color: white;
        color: #b0b1b3;
        display: inline-block;
    }

    .video-head {
        height: 62px;
        display: flex;
        align-items: center;
        border-bottom: 1px solid #e3e3e3;
    }

    .stu-name {
        flex: 1;
        padding-left: 20px;
    }

    .del {
        margin-right: 20px;
    }

    .video-context {
        min-height: 100px;
        position: relative;
    }

    .video-foot {
        position: relative;
        display: flex;
        height: 90px;
        border-top: 1px solid #e3e3e3;
        /* align-items: flex-end; */
        padding: 0 10px;
        justify-content: space-around;
        flex-direction: column;
    }

    .video-page .iconfont:before {
        background-color: #b0b1b3;
        color: white;
    }

    .video-page .iconfont:hover:before {
        background-color: #0cc689;
    }

    .video-play {
        flex: 1;
        text-align: center;
    }

    .video-play .iconfont {
        font-size: 40px;
        color: #0cc689;
    }

    .video-time {
        color: #b0b1b3;
    }

    .video-progress {
        top: -2px;
        left: 0;
        color: #0cc689;
        width: 100%;
        text-align: left;
        height: 16px;
        padding: 3px 5px;
        line-height: 7px;
        background: #e7f9f3;
        border-radius: 4.5px;
    }

    .video-progress .line {
        height: 7px;
        display: inline-block;
        background-color: #5cedbd;
        vertical-align: middle;
        min-width: 9px;
        border-radius: 4.5px;
        box-shadow: 0 0 8px #5cedbd;
    }

    .video-progress .video-dot {
        display: inline-block;
        width: 9px;
        height: 9px;
        background-color: #0cc689;
        border-radius: 4.5px;
        margin-top: -1px;
        margin-left: -4px;
        box-shadow: 0 0 8px rgba(12, 198, 137, .6);
        float: right;
    }
</style>
<style>
    .video-speed .el-input--mini .el-input__inner {
        width: 90px;
        border: none;
        color: #b0b1b3;
        font-size: 16px;
        padding-bottom: 2px;
    }

    .video-info {
        display: flex;
        align-items: center;
        width: 100%;
    }

    .el-dialog__body {
        padding: 30px 20px 10px;
        color: #606266;
        font-size: 14px;
    }
</style>
